package cn.xuexiluxian.open.admin.controller.system;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import cn.xuexiluxian.open.common.annotation.Log;
import cn.xuexiluxian.open.common.annotation.RepeatSubmit;
import cn.xuexiluxian.open.common.constant.Constants;
import cn.xuexiluxian.open.common.enums.BusinessType;
import cn.xuexiluxian.open.common.enums.ResultStatusCodeEnum;
import cn.xuexiluxian.open.common.response.ResponseResult;
import cn.xuexiluxian.open.system.model.dto.SystemUnitDTO;
import cn.xuexiluxian.open.system.model.entity.SystemUnit;
import cn.xuexiluxian.open.system.model.entity.SystemUser;
import cn.xuexiluxian.open.system.service.ISystemUnitService;
import cn.xuexiluxian.open.system.service.ISystemUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 机构管理
 * @author 王俊南
 * 2022-07-16
 */
@Slf4j
@RestController
@RequestMapping("system/unit")
public class SystemUnitController {
    @Autowired
    private ISystemUnitService systemUnitService;
    @Autowired
    private ISystemUserService systemUserService;

    /**
     * 机构列表
     * @param systemUnit
     * @return
     */
    @GetMapping("list")
    @Log(title = "机构管理", businessType = BusinessType.SELECT)
    @PreAuthorize("@permission.hasPermission('system:unit:list')")
    public ResponseResult list(SystemUnit systemUnit){
        LambdaQueryWrapper<SystemUnit> queryWrapper = Wrappers.<SystemUnit>lambdaQuery()
                .eq(systemUnit.getEnabled() != null, SystemUnit::getEnabled, systemUnit.getEnabled())
                .eq(StrUtil.isNotBlank(systemUnit.getCode()), SystemUnit::getCode, systemUnit.getCode())
                .like(StrUtil.isNotBlank(systemUnit.getName()), SystemUnit::getName, systemUnit.getName());
        List<SystemUnit> list = systemUnitService.list(queryWrapper);
        return ResponseResult.ok(list);
    }

    /**
     * 机构树
     * @param systemUnit
     * @return
     */
    @GetMapping("tree")
    @Log(title = "机构管理", businessType = BusinessType.SELECT)
    @PreAuthorize("@permission.hasPermission('system:unit:tree')")
    public ResponseResult tree(SystemUnit systemUnit){
        LambdaQueryWrapper<SystemUnit> queryWrapper = Wrappers.<SystemUnit>lambdaQuery()
                .eq(true, SystemUnit::getEnabled, 1)
                .eq(StrUtil.isNotBlank(systemUnit.getCode()), SystemUnit::getCode, systemUnit.getCode())
                .like(StrUtil.isNotBlank(systemUnit.getName()), SystemUnit::getName, systemUnit.getName());

        List<SystemUnit> list = systemUnitService.list(queryWrapper);

        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setWeightKey("code");
        List<Tree<String>> trees = TreeUtil.build(list, Constants.UNIT_ROOT_ID, treeNodeConfig, (treeNode, tree) -> {
            tree.setId(treeNode.getId());
            tree.setParentId(treeNode.getParentId());
            tree.setName(treeNode.getName());
            tree.setWeight(treeNode.getCode());
            // 扩展属性 ...
            tree.putExtra("codeseq", treeNode.getCodeseq());
            tree.putExtra("contact", treeNode.getContact());
            tree.putExtra("mobile", treeNode.getMobile());
            tree.putExtra("address", treeNode.getAddress());
            tree.putExtra("email", treeNode.getEmail());
            tree.putExtra("web", treeNode.getWeb());
            tree.putExtra("hasChildren", treeNode.getHasChildren());
            tree.putExtra("system", treeNode.getSystem());
            tree.putExtra("enabled", treeNode.getEnabled());
            tree.putExtra("leaderId", treeNode.getLeaderId());
            tree.putExtra("createTime", treeNode.getCreateTime());
        });
        return ResponseResult.ok(trees);
    }

    /**
     * 添加机构
     * @param systemUnitDTO
     * @return
     */
    @RepeatSubmit
    @PostMapping("add")
    @Log(title = "机构管理", businessType = BusinessType.INSERT)
    @PreAuthorize("@permission.hasPermission('system:unit:add')")
    public ResponseResult addnew(@RequestBody SystemUnitDTO systemUnitDTO){
        if(StrUtil.isBlank(systemUnitDTO.getName())){
            return ResponseResult.error(ResultStatusCodeEnum.PARAM_REQUIRE_ERROR);
        }
        boolean b = systemUnitService.add(systemUnitDTO);
        if(b){
            return ResponseResult.ok();
        }
        return ResponseResult.error(ResultStatusCodeEnum.HTTP_ERROR);
    }

    /**
     * 添加机构
     * @param systemUnitDTO
     * @return
     */
    @RepeatSubmit
    @PostMapping("update")
    @Log(title = "机构管理", businessType = BusinessType.UPDATE)
    @PreAuthorize("@permission.hasPermission('system:unit:update')")
    public ResponseResult update(@RequestBody SystemUnitDTO systemUnitDTO){
        if(systemUnitDTO == null || StrUtil.isBlank(systemUnitDTO.getId()) || StrUtil.isBlank(systemUnitDTO.getName())){
            return ResponseResult.error(ResultStatusCodeEnum.PARAM_REQUIRE_ERROR);
        }
        boolean b = systemUnitService.modify(systemUnitDTO);
        if(b){
            return ResponseResult.ok();
        }
        return ResponseResult.error(ResultStatusCodeEnum.HTTP_ERROR);
    }

    /**
     * 机构详情
     * @param id
     * @return
     */
    @GetMapping("get/{id}")
    @Log(title = "机构管理", businessType = BusinessType.SELECT)
    @PreAuthorize("@permission.hasPermission('system:unit:get')")
    public ResponseResult get(@PathVariable String id){
        if(StrUtil.isBlank(id)){
            return ResponseResult.error(ResultStatusCodeEnum.PARAM_REQUIRE_ERROR);
        }
        SystemUnit systemUnit = systemUnitService.getById(id);
        if(systemUnit != null){
            return ResponseResult.ok(systemUnit);
        }
        return ResponseResult.error(ResultStatusCodeEnum.DATA_NO_EXIST);
    }

    /**
     * 删除机构
     * @param id
     * @return
     */
    @RepeatSubmit
    @GetMapping("delete/{id}")
    @Log(title = "机构管理", businessType = BusinessType.DELETE)
    @PreAuthorize("@permission.hasPermission('system:unit:delete')")
    public ResponseResult delete(@PathVariable String id){
        if(StrUtil.isBlank(id)){
            return ResponseResult.error(ResultStatusCodeEnum.PARAM_REQUIRE_ERROR);
        }
        if(Constants.UNIT_ROOT_ID.equals(id)){
            return ResponseResult.error(ResultStatusCodeEnum.BUILT_IN_DATA_NODELETE);
        }

        QueryWrapper<SystemUnit> queryWrapper = new QueryWrapper<SystemUnit>();
        queryWrapper.eq("parent_id", id);
        List<SystemUnit> list = systemUnitService.list(queryWrapper);
        if(list != null && list.size() > 0){
            return ResponseResult.error(ResultStatusCodeEnum.DATA_HAS_CHILDREN);
        }

        QueryWrapper<SystemUser> queryWrapper1 = new QueryWrapper<SystemUser>();
        queryWrapper1.eq("unit_id", id);
        List<SystemUser> users = systemUserService.list(queryWrapper1);
        if(users != null && users.size() > 0){
            return ResponseResult.error(ResultStatusCodeEnum.DATA_HAS_RESOURCES);
        }

        SystemUnit systemUnit = systemUnitService.getById(id);

        if(systemUnit.getSystem() == 1){
            return ResponseResult.error(ResultStatusCodeEnum.BUILT_IN_DATA_NODELETE);
        }
        boolean b = systemUnitService.delete(systemUnit);
        if(b){
            return ResponseResult.ok();
        }
        return ResponseResult.error(ResultStatusCodeEnum.DATA_NO_EXIST);
    }
}
